﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Elements
{
    /// <summary>
    /// 形状基类
    /// </summary>
    public abstract class ShapeBaseV5
    {        
        /// <summary>
        /// 连接点
        /// </summary>
        public enum ShapeLinkPoints
        {
            左,
            上,
            右,
            下,
        }
        /// <summary>
        /// 形状ID
        /// </summary>
        public string Id { get; set; }
        /// <summary>
        /// 形状位置和尺寸
        /// </summary>
        public Rectangle Rect { get; set; }
        /// <summary>
        /// 背景颜色
        /// </summary>
        public Color BackgroundColor { get; set; }
        /// <summary>
        /// 形状内的文本
        /// </summary>
        public string Text { get; set; }
        /// <summary>
        /// 文本字体
        /// </summary>
        public Font TextFont { get; set; }
        /// <summary>
        /// 文本颜色
        /// </summary>
        public Color FontColor { get; set; }

        /// <summary>
        /// 获取连接点坐标
        /// </summary>
        /// <param name="linkPoint"></param>
        /// <returns></returns>
        public virtual Point GetLinkPoint(ShapeLinkPoints linkPoint)
        {
            //默认实现以矩形为基础，取矩形四边中点坐标。

            int ptX = 0;
            int ptY = 0;
            switch (linkPoint)
            {
                case ShapeLinkPoints.左:
                    ptX = Rect.X;
                    ptY = Rect.Y + Rect.Height / 2;
                    break;
                case ShapeLinkPoints.上:
                    ptX = Rect.X + Rect.Width / 2;
                    ptY = Rect.Y;
                    break;
                case ShapeLinkPoints.右:
                    ptX=Rect.X + Rect.Width;
                    ptY = Rect.Y + Rect.Height / 2;
                    break;
                case ShapeLinkPoints.下:
                default:
                    ptX = Rect.X + Rect.Width / 2;
                    ptY = Rect.Y + Rect.Height;
                    break;
            }
            return new Point(ptX, ptY);
        }
        
        //V3新增

        /// <summary>
        /// 获取连接点小矩形区域
        /// </summary>
        /// <param name="linkPoint"></param>
        /// <returns></returns>
        public virtual Rectangle GetLinkRect(ShapeLinkPoints linkPoint)
        {
            int ptX = 0;
            int ptY = 0;
            int w = 10, h = 10, w_half = 5, h_half = 5;
            switch (linkPoint)
            {
                case ShapeLinkPoints.左:
                    ptX = Rect.X- w_half;
                    ptY = Rect.Y + Rect.Height / 2- h_half;
                    break;
                case ShapeLinkPoints.上:
                    ptX = Rect.X + Rect.Width / 2 - w_half;
                    ptY = Rect.Y - h_half;
                    break;
                case ShapeLinkPoints.右:
                    ptX=Rect.X + Rect.Width - w_half;
                    ptY = Rect.Y + Rect.Height / 2 - h_half;
                    break;
                case ShapeLinkPoints.下:
                default:
                    ptX = Rect.X + Rect.Width / 2 - w_half;
                    ptY = Rect.Y + Rect.Height - h_half;
                    break;
            }
            return new Rectangle(ptX, ptY,w,h);
        }
        /// <summary>
        /// 获取所有连接点小矩形区域
        /// </summary>
        /// <returns></returns>
        public List<Rectangle> GetAllLinkRects()
        {
            return new List<Rectangle>()
            {
                GetLinkRect(ShapeLinkPoints.左),
                GetLinkRect(ShapeLinkPoints.上),
                GetLinkRect(ShapeLinkPoints.右),
                GetLinkRect(ShapeLinkPoints.下),
            };
        }

        private void DrawLinkRect(Graphics g, ShapeLinkPoints linkPoint, Brush fill, Pen pen)
        {
            var rect = GetLinkRect(linkPoint);
            DrawLinkRect(g, rect, fill, pen);
        }

        private void DrawLinkRect(Graphics g, Rectangle rect, Brush fill, Pen pen)
        {            
            var gp = GetShapeGPath(rect);
            g.FillPath(fill, gp);
            g.DrawPath(pen, gp);            
        }

        /// <summary>
        /// 绘制所有连接点
        /// </summary>
        public virtual void DrawAllLinkRects(Graphics g)
        {
            var ls = GetAllLinkRects();
            ls.ForEach(a => DrawLinkRect(g, a, Brushes.Red, Pens.White));
        }

        /// <summary>
        /// 绘制选中的连接点
        /// </summary>
        /// <param name="g"></param>
        /// <param name="linkPoint"></param>
        public virtual void DrawSelectedLinkRect(Graphics g, ShapeLinkPoints linkPoint)
        {
            DrawLinkRect(g, linkPoint, Brushes.Red, Pens.White);
        }

        /// <summary>
        /// 绘制鼠标移动到连接点上时的聚焦状态
        /// </summary>
        /// <param name="g"></param>
        /// <param name="linkPoint"></param>
        public virtual void DrawFocusedLinkRect(Graphics g, ShapeLinkPoints linkPoint)
        {
            DrawLinkRect(g, linkPoint, Brushes.Red, new Pen(Brushes.Yellow, 2));
        }
        /// <summary>
        /// 鼠标点是否在连接点区域内
        /// </summary>
        /// <param name="mousePt"></param>
        /// <returns></returns>
        public virtual bool IsHitLinkRect(Point mousePt)
        {
            var ls = GetAllLinkRects();
            var index = ls.FindIndex(a => GetShapeGPath(a).IsVisible(mousePt));
            return index >= 0;
            
        }
        /// <summary>
        /// 鼠标点所处的连接点
        /// </summary>
        /// <param name="mousePt"></param>
        /// <returns></returns>
        public virtual ShapeLinkPoints GetHitLinkRect(Point mousePt)
        {
            var ls = GetAllLinkRects();
            var index = ls.FindIndex(a => GetShapeGPath(a).IsVisible(mousePt));            
            if (index < 0)
            {
                return ShapeLinkPoints.左;//没找到鼠标点所处的连接点，默认返回一个值
            }
            else
            {
                return (ShapeLinkPoints)index;
            }
        }

        //V5-PART2增加

        /// <summary>
        /// 鼠标点是否在连接点区域内
        /// </summary>
        /// <param name="mousePt"></param>
        /// <returns></returns>
        public virtual bool IsHitShape(Point mousePt)
        {
            var gp = GetShapeGPath(Rect);
            return gp.IsVisible(mousePt);
        }

        /// <summary>
        /// 获取形状所形成的闭合路径
        /// </summary>
        /// <returns></returns>
        public virtual GraphicsPath GetShapeGPath(Rectangle rect)
        {
            //默认以矩形实现
            var gp = new GraphicsPath();
            gp.Reset();
            gp.AddRectangle(rect);
            gp.CloseFigure();
            return gp;
        }

        /// <summary>
        /// 绘制形状
        /// </summary>
        /// <param name="g"></param>
        public virtual void Draw(Graphics g)
        {
            var path = GetShapeGPath(Rect);
            g.FillPath(new SolidBrush(BackgroundColor), path);
            g.DrawString(Text, TextFont, new SolidBrush(FontColor), Rect,
                new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
        }

    }
}
